/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package aeropuertosol_hebras;

/**
 *
 * @author Java I
 */
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

class Aeropuerto implements Runnable{ // para que se puedan crear varios simultaneos interactuando

	Set aviones;					// Estado del aeropuerto
	final int CAPACIDAD;			// Número máximo de aviones que el aeropuerto puede atender
	static final String fComp = "companias.txt";
	static Map compañías;			// Map con los nombres de las compañías aéreas
									//     nombre de compañía -> acrónimo
	int tamañoSlot;					// Tamaño del slot

        static ArrayList<Aeropuerto> aeropuertos = new ArrayList<Aeropuerto>();
        String nombre;

	static protected Random rnd = new Random();

	public Aeropuerto(int capac, int tamSlot, String nombre) throws IOException {
		aviones = new HashSet();
		CAPACIDAD = capac;
		tamañoSlot = tamSlot;
		if (compañías == null) {
			this.lecturaCompañías();
		}
                aeropuertos.add(this);
                this.nombre=nombre;
	}



	public Aeropuerto(int capac, String nombre) throws IOException {
		this(capac, 2, nombre);

	}

    public String getNombre() {
        return nombre;
    }



        //redeficion del metodo run
        @Override
        public void run(){
            try {
                simulación("informe" + Thread.currentThread().getName() + ".txt", 4, 24);
            } catch (IOException ex) {
                Logger.getLogger(Aeropuerto.class.getName()).log(Level.SEVERE, null, ex);
            }
    //        System.out.println("Este es el Aeropuerto: " + Thread.currentThread().getName());
        }
        

	protected void lecturaCompañías() throws IOException {
		BufferedReader bf = new BufferedReader(new FileReader(fComp));
		lecturaCompañías(bf);
		bf.close();
	}

	protected void lecturaCompañías(BufferedReader bf) throws IOException {
		compañías = new HashMap();
		String c = bf.readLine();
		while (c != null) {
			String ac = (String) compañías.get(c);
			if (ac == null) {
				ac = acrónimo(c);
				if (compañías.values().contains(ac)) {
					throw new IllegalArgumentException("Acrónimo repetido");
				} else {
					compañías.put(c, ac);
				}
			}
			c = bf.readLine();
		}
	}

	static protected String acrónimo(String compañía) {
		StringTokenizer st = new StringTokenizer(compañía, " -");
		String acrónimo = "";
		if (st.hasMoreTokens()) {
			String primera = st.nextToken();
			acrónimo += primera.charAt(0);
			if (st.hasMoreTokens()) {
				acrónimo += st.nextToken().charAt(0);
			} else {
				acrónimo += primera.charAt(1);
			}
		} else {
			throw new IllegalArgumentException("Nombre de compañía vacío.");
		}
		return acrónimo.toUpperCase();
	}

	public void simulación(String salida, int intentos, int slots)  throws IOException {
		PrintWriter informe = new PrintWriter(new FileWriter(salida));
		simulación(informe, intentos, slots);
		informe.close();
	}

        //maxSimultaneos es el num de vuelos simultaneos que puede haber en el slot
	public synchronized void simulación(PrintWriter informe, int maxSimultaneos, int slots) {
		for (int i = 1; i <= slots; i ++) {
			informe.println("slot " + i + ":");
			informe.println("\tAviones en el aeropuerto: " + aviones +
							" (" + aviones.size() + ")");

			int vuelosAter = rnd.nextInt(maxSimultaneos);	// Número de vuelos que se aproximan al aeropuerto
			int vuelosDesp = rnd.nextInt(maxSimultaneos);	// Número de vuelos que intentan despegar
			String ac = "";
			Iterator iter;
			Vuelo v;
			int p;

			int movsSlot = 0, 		// número de movimientos en el presente slot
				aterrizajes = 0;	// número de aterrizajes en el presente slot

			informe.println("\tPeticiones de aterrizaje:");

			while (movsSlot < tamañoSlot && aterrizajes < vuelosAter) {
				v = generaVuelo();
				if (aviones.size() < CAPACIDAD) {
					v.aterriza(i);
					aviones.add(v);
					informe.println ("\t\t" + v + " aterriza");
					movsSlot ++;
				} else {

					informe.println ("\t\t" + v + " desviado a otro aeropuerto");
				}
				aterrizajes ++;
			}

			informe.println("\tDespegues: ");

			int despegues = 0;	// número de despeguesen el presente slot

			iter = aviones.iterator();
			while (movsSlot < tamañoSlot && despegues < vuelosDesp && iter.hasNext()) {
				v = (Vuelo) iter.next();
				v.despega(i);
				iter.remove();
				informe.println("\t\t" + v);
				despegues ++;
				movsSlot ++;
			}
		}
                notifyAll();
	}

	protected synchronized Vuelo generaVuelo() {
		List acrónimos = new ArrayList(compañías.values());
		String ac = (String) acrónimos.get(rnd.nextInt(compañías.size()));

                Aeropuerto origen = this;
                Aeropuerto destino=origen;
                while(origen.getNombre().equals(destino.getNombre())){
                    destino = aeropuertos.get(rnd.nextInt(aeropuertos.size()));
                }

                notifyAll();

                System.out.println("Este es el Aeropuerto: " + Thread.currentThread().getName());
                System.out.println("Generando vuelo "+ origen.getNombre() +"-"+destino.getNombre()+"\n");

		return new Vuelo(ac, origen, destino);

	}
}
			